package com.ladlee.session;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ladlee.enums.ResultEnum;
import com.ladlee.utils.ResultUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.util.UrlUtils;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Auther: dingchang
 * @Date: 2018/12/25 09:53
 * @Description: session的管理策略（过期，失效）
 */
@Slf4j
@Data
public class AbstractSessionManagerStrategy {

    /**
     * session过期跳转的URL
     */
    private String sessionDestinationUrl;

    /**
     * 跳转之前是否创建新的session
     */
    private boolean createNewSession = true;

    ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 重定向策略
     */
    private RedirectStrategy redirectStrategy;

    public AbstractSessionManagerStrategy(String sessionDestinationUrl){
        Assert.isTrue(UrlUtils.isValidRedirectUrl(sessionDestinationUrl),"url must start with '/' or with 'http(s)'");
        Assert.isTrue(StringUtils.endsWithIgnoreCase(sessionDestinationUrl, ".html"), "url must end with '.html'");
        this.sessionDestinationUrl = sessionDestinationUrl;
    }

    protected void onSessionInvalid(HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("session失效，进入AbstractSessionManagerStrategy配置onSessionInvalid的session管理策略其中");
        if(this.createNewSession){
            request.getSession();
        }

        //请求的路径
        String requestURI = request.getRequestURI();
        //目标路径
        String targetUrl;
        if(StringUtils.endsWithIgnoreCase("",".html")){ //如果请求是以.html结尾的，则将请求重定向到session失效页面
            targetUrl = sessionDestinationUrl;
            log.info("将.html的请求重定向到session失效页面{}",targetUrl);
            redirectStrategy.sendRedirect(request,response,targetUrl);
        }else{
            //以json字符串的形式响应
            Object content = buildResponseContent();
            response.setStatus(HttpStatus.UNAUTHORIZED.value()); //响应状态
            response.setContentType("application/json;charset=UTF-8"); //响应类型
            response.getWriter().write(objectMapper.writeValueAsString(content));
        }
    }

    /**
     * 构建相应内容
     * @return
     */
    public Object buildResponseContent(){
        String message = "session失效";
        if(this.isConcurrency()){
            message = message + "，并发登陆导致session失效";
        }
        return ResultUtils.error(ResultEnum.SESSION_INVALID.getCode(),message);
    }

    /**
     * 是否是并发登陆
     * @return
     */
    public boolean isConcurrency(){
        return false;
    }
}
